/**
 * 
 */
package kr.co.insoft.driver;

import kr.co.insoft.driver.exception.DriverException;
import kr.co.insoft.driver.exception.ExceptionCode;
import kr.co.insoft.driver.exception.NotSupportedException;
import kr.co.insoft.driver.model.CloudSponsor;

/**
 * CloudSponsor를 기반으로 해당하는 드라이버를 반환한다.
 * 
 * @see CloudSponsor
 * @author IN-SOFT Inc. GoodwillDD(sylee@in-soft.co.kr)
 * 
 */
public class DriverFactory {

	public static final String AMAZON_PACKAGE_CLASS = "kr.co.insoft.driver.amazon.impl.AmazonDriverImpl";
	public static final String RACKSPACE_US_PACKAGE_CLASS = "kr.co.insoft.driver.rackspace.RackSpaceDriver";
	public static final String RACKSPACE_UK_PACKAGE_CLASS = "kr.co.insoft.driver.rackspace.RackSpaceDriver";
	public static final String OPENSTACK_PACKAGE_CLASS = "kr.co.insoft.driver.openstack.OpenStackDriver";
	public static final String US_PROVIDER = "rackspace-cloudservers-us";
	public static final String UK_PROVIDER = "rackspace-cloudservers-uk";
	public static final String OPENSTACK_PROVIDER = "openstack-nova";

	/**
	 * 드라이버 클래스를 반환한다.
	 * 
	 * @param sponsor
	 * @param accessKey
	 *            (AMAZON : AccessKey(APIKEY) / RackSpace : USERNAME
	 * @param secretKey
	 *            (AMAZON : SecretKey / RackSpace : apiKey
	 * @return
	 * @throws DriverException
	 */
	public static Drivers getDrivers(CloudSponsor sponsor, String accessKey,
			String secretKey) throws DriverException, NotSupportedException {
		try {
			Drivers driver = null;
			switch (sponsor) {
			case AMAZON:
				driver = (Drivers) Class.forName(AMAZON_PACKAGE_CLASS)
						.newInstance();
				driver.setAccessKey(accessKey);
				driver.setSecretKey(secretKey);
				return driver;
			case RACKSPACE_US:
				driver = (Drivers) Class.forName(RACKSPACE_US_PACKAGE_CLASS)
						.newInstance();
				driver.setProvider(US_PROVIDER);
				driver.setUsername(accessKey);
				driver.setApiKey(secretKey);
				return driver;
			case RACKSPACE_UK:
				driver = (Drivers) Class.forName(RACKSPACE_UK_PACKAGE_CLASS)
						.newInstance();
				driver.setProvider(UK_PROVIDER);
				driver.setUsername(accessKey);
				driver.setApiKey(secretKey);
				return driver;
			case OPENSTACK:
				driver = (Drivers) Class.forName(OPENSTACK_PACKAGE_CLASS)
						.newInstance();
				driver.setProvider(OPENSTACK_PROVIDER);
				driver.setUsername(accessKey);
				driver.setAccessKey(secretKey);
				return driver;
			default:
				throw new NotSupportedException(ExceptionCode.NOT_SUPPORTED);
			}
		} catch (InstantiationException | IllegalAccessException
				| ClassNotFoundException e) {
			throw new NotSupportedException(ExceptionCode.NOT_SUPPORTED, e);
		}
	}

	/**
	 * 드라이버 클래스를 반환한다.
	 * 
	 * <pre>
	 * 사용시 반드시 해당 드라이버의 기본 설정 정보를 수동으로 입력하여야한다.
	 * Amazon : setAccessKey / setSecretKey
	 * RackSpace : setUsername / setApiKey
	 * </pre>
	 * 
	 * @param sponsor
	 * @return
	 * @throws DriverException
	 */
	public static Drivers getDrivers(CloudSponsor sponsor)
			throws DriverException, NotSupportedException {
		try {
			Drivers driver = null;
			switch (sponsor) {
			case RACKSPACE_UK:
				driver = (Drivers) Class.forName(RACKSPACE_UK_PACKAGE_CLASS)
						.newInstance();
				driver.setProvider(UK_PROVIDER);
				return driver;
			case RACKSPACE_US:
				driver = (Drivers) Class.forName(RACKSPACE_US_PACKAGE_CLASS)
						.newInstance();
				driver.setProvider(US_PROVIDER);
				return driver;
			case AMAZON:
				driver = (Drivers) Class.forName(AMAZON_PACKAGE_CLASS)
						.newInstance();
				return driver;
			case OPENSTACK:
				driver = (Drivers) Class.forName(OPENSTACK_PACKAGE_CLASS)
						.newInstance();
				driver.setProvider(OPENSTACK_PROVIDER);				
				return driver;
			default:
				throw new NotSupportedException(ExceptionCode.NOT_SUPPORTED);
			}
		} catch (Exception e) {
			throw new NotSupportedException(ExceptionCode.NOT_SUPPORTED, e);
		}

	}
}
